package cm.example.shoppingplatformspringboot.service;


import cm.example.shoppingplatformspringboot.entity.Category;
import cm.example.shoppingplatformspringboot.entity.Goods;
import cm.example.shoppingplatformspringboot.entity.Manager;
import cm.example.shoppingplatformspringboot.entity.User;
import cm.example.shoppingplatformspringboot.mapper.AdminMapper;
import jakarta.annotation.Resource;
import org.jetbrains.annotations.NotNull;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.Cursor;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ScanOptions;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Service
public class AdminService {
    @Resource
    private AdminMapper adminMapper;
    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    /**
     * 添加管理员账户
     *
     * @param manager 管理员实体对象，必须包含：
     *                - account   : 登录账号（需唯一）
     *                - password  : 明文密码（自动加密存储）
     * @return {@code  int} 受影响行数（1-成功，0-失败）
     * @implNote 自动执行：
     * 1. MD5加密密码（使用Spring DigestUtils）
     * 2. 设置默认状态为1（正常）
     */
    public int addAdmin(Manager manager) {
        // 对密码进行MD5加密
        manager.setPassword(DigestUtils.md5DigestAsHex(manager.getPassword().getBytes()));
        return adminMapper.addAdmin(manager);
    }

    /**
     * 修改管理员账户信息
     *
     * @param manager 必须包含：
     *                - id        : 有效管理员ID
     *                - password  : 新明文密码
     * @return {@code  int} 受影响行数（1-成功，0-失败）
     */
    public int editAdmin(Manager manager) {
        // 对密码进行MD5加密
        manager.setPassword(DigestUtils.md5DigestAsHex(manager.getPassword().getBytes()));
        return adminMapper.editAdmin(manager);
    }

    /**
     * 逻辑删除管理员账户
     *
     * @param id 管理员ID
     * @return 操作结果：
     * - 1: 删除成功
     * - 0: 记录不存在
     */
    public int deleteAdmin(int id) {
        return adminMapper.deleteAdmin(id);
    }

    /**
     * 获取所有管理员列表
     *
     * @return 管理员列表
     */
    public List<Manager> getAdminList() {
        return adminMapper.getAdminList();
    }

    /**
     * 禁用管理员账户
     *
     * @param id 管理员ID
     * @return 操作结果：
     * - 1: 禁用成功
     * - 0: 禁用失败
     */
    public int disableAdmin(int id) {
        return adminMapper.disableAdmin(id);
    }

    /**
     * 解禁管理员账户
     *
     * @param id 管理员ID
     * @return 操作结果：
     * - 1: 解禁成功
     * - 0: 解禁失败
     */
    public int unDisableAdmin(int id) {
        return adminMapper.unDisableAdmin(id);
    }

    /**
     * 获取所有用户列表
     *
     * @return 用户列表
     */
    public List<User> getUserList() {
        return adminMapper.getUserList();
    }

    /**
     * 删除用户
     *
     * @param id 用户ID
     * @return 操作结果：
     * - 1: 删除成功
     * - 0: 删除失败
     */
    public int deleteUser(int id) {
        return adminMapper.deleteUser(id);
    }

    /**
     * 拉黑用户
     *
     * @param id 用户ID
     * @return 操作结果：
     * - 1: 拉黑成功
     * - 0: 拉黑失败
     */
    public int blockUser(int id) {
        return adminMapper.blockUser(id);
    }

    /**
     * 解除拉黑用户
     *
     * @param id 用户ID
     * @return 操作结果：
     * - 1: 解除拉黑成功
     * - 0: 解除拉黑失败
     */
    public int unblockUser(int id) {
        return adminMapper.unblockUser(id);
    }

    /**
     * 冻结用户
     *
     * @param id 用户ID
     * @return 操作结果：
     * - 1: 冻结成功
     * - 0: 冻结失败
     */
    public int freezeUser(int id) {
        return adminMapper.freezeUser(id);
    }

    /**
     * 解冻用户
     *
     * @param id 用户ID
     * @return 操作结果：
     * - 1: 解冻成功
     * - 0: 解冻失败
     */
    public int unfreezeUser(int id) {
        return adminMapper.unfreezeUser(id);
    }

    /**
     * 添加商品类型
     *
     * @param name 商品类型名称
     * @return 操作结果：
     * - 1: 添加成功
     * - 0: 添加失败
     */
    public int addProductType(String name) {
        return adminMapper.addProductType(name);
    }

    /**
     * 获取所有商品类型列表
     *
     * @return 商品类型列表
     */
    public List<Category> getProductTypeList() {
        return adminMapper.getProductTypeList();
    }

    /**
     * 删除商品类型
     *
     * @param id 商品类型ID
     * @return 操作结果：
     * - 0: 商品类型不存在或仍有商品关联
     * - 1: 删除成功
     */
    public int deleteProductType(int id) {
        int res = adminMapper.getProductNumber(id);
        if (res == 0) {
            adminMapper.deleteProductType(id);
        }
        return res;
    }

    /**
     * 获取所有商品列表
     *
     * @return 商品列表
     */
    public List<Goods> selectAll() {
        return adminMapper.selectAll();
    }

    /**
     * 获取分类ID-名称映射表
     *
     * @return 分类ID-名称映射表列表
     */
    public List<Map<String, Object>> getAllShopGenres() {
        return adminMapper.getAllShopGenres();
    }

    /**
     * 按分类名称获取商品列表
     *
     * @param value 分类名称
     * @return 商品列表
     */
    public List<Goods> getGoodsListByGenre(String value) {
        return adminMapper.getGoodsListByGenre(value);
    }

    /**
     * 商品名称模糊搜索
     *
     * @param input 搜索参考
     * @return 匹配的商品列表
     */
    public List<Goods> searchGoods(String input) {
        return adminMapper.searchGoods(input);
    }

    /**
     * 商品名称自动补全搜索
     *
     * @param name 商品名称前缀
     * @return 匹配的商品名称列表
     */
    public List<String> searchGoodsByName(String name) {
        return adminMapper.searchGoodsByName(name);
    }

    /**
     * 删除商品
     *
     * @param id 商品ID
     * @return 操作结果：
     * - 1: 删除成功
     * - 0: 删除失败
     */
    public int deleteGoods(int id) {
        // 1. 删除商品
        int result= adminMapper.deleteGoods(id);
        // 2. 清除所有分页缓存
        deleteKeysByPattern("goodsList:page:*");
        return result;
    }

    /**
     * 下架商品
     *
     * @param id 商品ID
     * @return 操作结果：
     * - 1: 下架成功
     * - 0: 下架失败
     */
    public int putOnShelfGoods(int id) {
        int res = adminMapper.putOnShelfGoods(id);
        // 2. 清除所有分页缓存
        deleteKeysByPattern("goodsList:page:*");
        return res;
    }

    /**
     * 上架商品
     *
     * @param id 商品ID
     * @return 操作结果：
     * - 1: 上架成功
     * - 0: 上架失败
     */
    public int soldOutGoods(int id) {
        int res = adminMapper.soldOutGoods(id);
        // 2. 清除所有分页缓存
        deleteKeysByPattern("goodsList:page:*");
        return res;
    }

    /**
     * 添加商品
     *
     * @param goods 商品实体对象
     * @return 操作结果：
     * - 1: 添加成功
     * - 0: 添加失败
     */
    public int addGoods(Goods goods) {
        // 1. 添加商品
        int result = adminMapper.addGoods(goods);
        // 2. 清除所有分页缓存
        deleteKeysByPattern("goodsList:page:*");
        return result;
    }

    /**
     * 修改商品信息
     *
     * @param goods 商品实体对象，必须包含ID
     * @return 操作结果：
     * - 1: 修改成功
     * - 0: 修改失败
     */
    public int editGoods(Goods goods) {
        // 1. 修改商品
        int result = adminMapper.editGoods(goods);
        // 2. 清除所有分页缓存
        deleteKeysByPattern("goodsList:page:*");
        return result;
    }

    /**
     * 管理员登录
     *
     * @param account  登录账号
     * @param password 明文密码
     * @return 登录成功返回管理员信息，失败返回null
     * @implNote 自动执行：
     * 1. MD5加密密码验证
     * 2. 登录成功更新最后登录时间及IP
     */
    public Manager login(String account, String password, String last_login_ip) {
        Manager admin = adminMapper.getAdminByAccount(account);
        if (admin == null) {
            return null;
        }

        //将密码转为md5加密字段
        String encryptedPassword = DigestUtils.md5DigestAsHex(password.getBytes());
        if (!admin.getPassword().equals(encryptedPassword)) {
            return null;//密码错误
        }

        adminMapper.updateAdminLoginInfo(admin.getAccount(), last_login_ip);
        return adminMapper.getAdminByAccount(admin.getAccount());
    }

    /**
     * 注册新管理员
     *
     * @param manager 管理员实体对象，必须包含：
     *                - account   : 登录账号（需唯一）
     *                - password  : 明文密码
     * @return 注册结果：
     * - 1: 注册成功
     * - 0: 注册失败
     */
    public int registerAdmin(@NotNull Manager manager) {
        //将密码转为md5加密字段
        String password = DigestUtils.md5DigestAsHex(manager.getPassword().getBytes());
        manager.setPassword(password);
        //插入到数据库
        int result = adminMapper.addAdmin(manager);
        return result > 0 ? 1 : 0;
    }

    /**
     * 根据账号获取管理员信息
     *
     * @param account 管理员账号
     * @return 管理员信息实体对象，不存在返回null
     */
    public Manager getAdminByAccount(String account) {
        return adminMapper.getAdminByAccount(account);
    }

    /**
     * 判断管理员账号是否存在
     *
     * @param account 管理员账号
     * @return 存在返回true，不存在返回false
     */
    public boolean isAccountExists(String account) {
        return adminMapper.getAdminByAccount(account) != null;
    }

    // 使用SCAN命令安全删除匹配模式的键
    private void deleteKeysByPattern(String pattern) {
        redisTemplate.execute((RedisConnection connection) -> {
            // 构造 SCAN 选项
            ScanOptions options = ScanOptions.scanOptions()
                    .match(pattern)
                    .count(100)
                    .build();

            // 使用新的 keyCommands().scan(...) 接口
            Cursor<byte[]> cursor = connection.keyCommands().scan(options);
            List<byte[]> keys = new ArrayList<>();

            // 收集所有匹配的 key
            cursor.forEachRemaining(keys::add);

            if (!keys.isEmpty()) {
                // 可选：使用 del 同步删除
                //connection.keyCommands().del(keys.toArray(new byte[0][]));
                // 或者：使用 unlink 实现异步删除，推荐在大批量删除时使用
                connection.keyCommands().unlink(keys.toArray(new byte[0][]));
            }
            return null;
        });
    }

}
